var gulp = require("gulp");

var tmpDir = "tmp";
var testGlob = "src/**/!(*-browser)*-test.js";
var testOutput = "test.js";
var browserTestGlob = "src/**/*-browser-test.?(js|jsx)";
var browserTestOutput = "browser-test.js";
var jsLessRx = /\.js\.less$/;
var jsxRx = /\.jsx$/;
var rootSrcJs = "./src/editor.js";
var jsOutput = "editor.js";
var pageStyleSrc = "src/editor.less";
var pageSrc = "src/editor.html";
var watchLessGlob = "src/!(*.js).less";
var watchWebpackGlob = "src/**/+(!(*-test).js|*.js.less|*.jsx)";

gulp.task("webpack-node-test", function (done) {
    var webpack = require("gulp-webpack");

    var webpackOptions = {
        bail: true,
        output: {
            filename: testOutput
        }
    };

    return gulp.src(testGlob)
        .pipe(webpack(webpackOptions))
        .pipe(gulp.dest(tmpDir));
});

gulp.task("node-test", [
    "webpack-node-test"
], function () {
    var mocha = require("gulp-mocha");
    var flags = require("node-flags");
    var path = require("path");

    var mochaOptions = {
        ui: "tdd",
        bail: true
    };

    var grep = flags.get("grep");
    if (grep) {
        mochaOptions.grep = grep;
    }

    return gulp.src(path.join(tmpDir, testOutput), {read: false})
        .pipe(mocha(mochaOptions));
});

gulp.task("webpack-browser-test", function () {
    var webpack = require("gulp-webpack");

    var webpackOptions = {
        bail: true,
        module: {
            loaders: [{
                test: jsLessRx,
                loader: "style/useable!css!less"
            }, {
                test: jsxRx,
                loader: "jsx-loader"
            }]
        },
        output: {
            filename: browserTestOutput
        }
    };

    return gulp.src(browserTestGlob)
        .pipe(webpack(webpackOptions))
        .pipe(gulp.dest(tmpDir));
});

gulp.task("browser-test", [
    "node-test",
    "webpack-browser-test"
], function (done) {
    var karma = require("karma");
    var path = require("path");

    var karmaOptions = {
        browsers: ["PhantomJS"],
        client: {
            captureConsole: true,
            mocha: {
                ui: "tdd",
                bail: true
            }
        },
        colors: false,
        files: [
            path.join(tmpDir, browserTestOutput)
        ],
        frameworks: [
            "mocha"
        ],
        plugins: [
            require("karma-mocha"),
            require("karma-phantomjs-launcher")
        ],
        singleRun: true
    };

    karma.server.start(karmaOptions);
});

gulp.task("test", ["node-test", "browser-test"]);

gulp.task("webpack-dev", function () {
    var webpack = require("gulp-webpack");

    var webpackOptions = {
        bail: true,
        entry: {
            root: rootSrcJs
        },
        module: {
            loaders: [{
                test: jsLessRx,
                loader: "style/useable!css!less"
            }, {
                test: jsxRx,
                loader: "jsx-loader"
            }]
        },
        output: {
            filename: jsOutput
        }
    };

    return gulp.src(rootSrcJs)
        .pipe(webpack(webpackOptions))
        .pipe(gulp.dest(tmpDir));
});

gulp.task("style-dev", function () {
    var less = require("gulp-less");
    return gulp.src(pageStyleSrc)
        .pipe(less())
        .pipe(gulp.dest(tmpDir));
});

gulp.task("page-dev", [
    "webpack-dev",
    "style-dev"
], function () {
    return gulp.src(pageSrc)
        .pipe(gulp.dest(tmpDir));
});

gulp.task("watch", function () {
    gulp.watch(watchLessGlob, ["style-dev"]);
    gulp.watch(watchWebpackGlob, ["webpack-dev"]);
    gulp.watch(pageSrc, ["page-dev"]);
});

gulp.task("server-dev", [
    "page-dev",
    "watch"
], function () {
    var connect = require("gulp-connect");
    connect.server({
        root: tmpDir
    });
});

gulp.task("dev", ["server-dev"]);
